package com.xhwl.logistics.strategy.impl;


import com.xhwl.logistics.bo.VehicleParkingLotSecondBO;
import com.xhwl.logistics.bo.cent.ProjectBO;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.bo.manipulate.VehicleSyncBO;
import com.xhwl.logistics.converter.mapstruct.VehicleSyncConverter;
import com.xhwl.logistics.dto.http.CarNanTouDTO;
import com.xhwl.logistics.dto.http.query.QueryCarDTO;
import com.xhwl.logistics.entity.VehicleCar;
import com.xhwl.logistics.service.business.VehicleCarBusinessService;
import com.xhwl.logistics.service.cent.QueryProjectService;
import com.xhwl.logistics.service.impl.VehicleCarServiceImpl;
import com.xhwl.logistics.service.impl.VehicleParkingLotServiceImpl;
import com.xhwl.logistics.service.impl.http.NanTouHttpServiceImpl;
import com.xhwl.logistics.strategy.IVehicleParkingLotSyncHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
//@Service
public class VehicleParkingLotNanTouSyncHandlerImpl implements IVehicleParkingLotSyncHandler {

    @Autowired
    private NanTouHttpServiceImpl nanTouHttpService;

    @Autowired
    private VehicleCarServiceImpl vehicleCarService;

    @Autowired
    private QueryProjectService queryProjectService;

    @Autowired
    private VehicleParkingLotServiceImpl vehicleParkingLotService;

    @Autowired
    private VehicleSyncConverter vehicleSyncConverter;

    @Autowired
    private VehicleCarBusinessService vehicleCarBusinessService;

    @Async("threadPoolTaskExecutorForSchedule")
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void syncCarList(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleSyncBO vehicleSyncBO) {

        log.info("NanTou sync car list start!");
        log.info("NanTou sync car list vehicleIntegratedConfigBO: " + vehicleIntegratedConfigBO);

        Integer projectId = vehicleSyncBO.getProjectId();

        QueryCarDTO queryCarDTO = new QueryCarDTO();
        List<CarNanTouDTO> carNanTouDTOSList = nanTouHttpService.queryCarList(vehicleIntegratedConfigBO, queryCarDTO);

        //由于南投车牌号不是唯一的，所以需要使用车牌号和用户名双重String来作为唯一指标
        Map<String, CarNanTouDTO> mapForCarNanTouDTO = carNanTouDTOSList.stream()
                .collect(Collectors.toMap(s->{
                    return s.getOwnerName()+s.getPlateNumber()+"";
                }, Function.identity()));
        List<String> plateNumberFromNanTou = carNanTouDTOSList.stream()
                .map(s->{
                    return s.getOwnerName()+s.getPlateNumber()+"";
                })
                .collect(Collectors.toList());

        List<VehicleCar> vehicleCar = vehicleCarService.list(vehicleCarService.conditionFotQueryAliveCars(projectId));
        Map<String, Integer> mapForVehicleCarId = vehicleCar.stream()
                .collect(Collectors.toMap(s->{
                    return s.getOwnerName()+s.getPlateNumber()+"";
                }, VehicleCar::getId));
        List<String> plateNumberFromCentVehicleCar = vehicleCar.stream()
                .map(s->{
                    return s.getOwnerName()+s.getPlateNumber()+"";
                })
                .collect(Collectors.toList());

        List<String> add = ListUtils.subtract(plateNumberFromNanTou,plateNumberFromCentVehicleCar);
        if(!add.isEmpty()){
            ProjectBO projectBO = queryProjectService.queryProject(projectId);
            VehicleParkingLotSecondBO vehicleParkingLotSecondBO = vehicleParkingLotService.queryParkingLot(projectId, null);
            List<CarNanTouDTO> addForCarListFromNanTouDTOList = add.stream()
                    .map(mapForCarNanTouDTO::get)
                    .collect(Collectors.toList());
            List<VehicleCar> vehicleCars = vehicleSyncConverter.NanToutoVehicleCarList(addForCarListFromNanTouDTOList, projectId, projectBO.getProjectName(), vehicleParkingLotSecondBO.getId(), vehicleParkingLotSecondBO.getParkingLotName());
            vehicleCarService.saveBatch(vehicleCars);
        }

        List<String> delete = ListUtils.subtract(plateNumberFromCentVehicleCar, plateNumberFromNanTou);
        if(!delete.isEmpty()){
            List<Integer> carIdList = delete.stream()
                    .map(mapForVehicleCarId::get)
                    .collect(Collectors.toList());
            vehicleCarBusinessService.deleteCars(carIdList);
        }
        log.info("NanTou sync car list end!");
    }
}
